/* 
* sepmisc.h - This file is a part of the sep-library 
*
* Copyright (C) 2008 Jesper Schmidt Hansen 
* 
* License: GPL - see COPYING for copying conditions.
* There is ABSOLUTELY NO WARRANTY, not even for MERCHANTIBILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* Contact: schmidt@zigzak.net
*/


#ifndef __SEPMISC_H__
#define __SEPMISC_H__


#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#include <float.h>

#include "sepstrct.h"
#include "separray.h"
#include "sepdef.h"
#include "seputil.h"
#include "sepprfrc.h"
#include "sepret.h"
#include "sepmol.h"

/**
 * Flushes standard output
 */
#define SEP_FLUSH fflush(stdout)

/**
 * Macro for defining timer clock_t
 */ 
#define SEP_TICTOC clock_t time_then

/**
 * Set timer
 */
#define SEP_TIC time_then = clock()

/**
 * Get time now
 */
#define SEP_TOC ((int)((clock()-time_then)/CLOCKS_PER_SEC))


/**
 * Generates pseudo random uniform number
 */
#define sep_rand() ( rand()/(RAND_MAX+1.0) )

/**
 * Prints something to the screen and flushes 
 * Usefull for debugging
 */
#define sep_here(x) { printf("%d\n", x); SEP_FLUSH; }

/**
 * Squares input x
 */
#define sep_Sq(x) ( (x)*(x) )

/**
 * Evaluates the absolut value
 */ 
#define sep_Abs(x) ( (x) > 0.0  ? (x) : -(x) )

#ifndef DOXYGEN_SKIP

#define sep_Wrap( x, y )                          \
 {                                                \
 if ( x > 0.5*y ) x -= y;                         \
 else if  ( x < -0.5*y ) x += y;                  \
 }

#endif

#ifndef DOXYGEN_SKIP

#define sep_Periodic( x, y )                 \
 {                                           \
 if ( x > y ) x -= y;                        \
 else if  ( x < 0 ) x += y;                  \
 }

#endif 



void sep_error(char *str, ...);
void sep_warning(char *str, ...);

double sep_lj(double r2, char opt);
double sep_lj_shift(double r2, char opt);
double sep_wca(double r2, char opt);
double sep_spring_x0(double r2, char opt);

int sep_reaction_1_order(seppart *ptr, const char *reaction, 
			 double crp, int npart);
int sep_reaction_1_order_binomial(seppart *ptr, const char *reaction, 
			 double crp, int npart);
unsigned int sep_reaction_2_order(seppart *ptr,  const char *rstr, 
				  double cr, double Pcr, double Q, 
				  sepsys sys);

void sep_save(seppart *ptr, size_t npart, const char *file);
void sep_load(seppart *ptr, int nneighb, size_t npart, const char *file);

void sep_relax_temp(seppart *ptr, char type, double Td, double tau, sepsys sys);
void sep_scale_vel_index(seppart *ptr, double Td, int Id, int ndim);
void sep_scale_vel(seppart *ptr, char type, double Td, int npart, 
		   int ndim);
void sep_constraint_temp(seppart *ptr, char type, int npart, int ndim);

void sep_reset_force(seppart *ptr, sepsys *sys);

int sep_is_here(seppart *ptr, double min, 
		double max, int i, int dir);

void sep_get_xp(seppart*ptr, double dt, int npart, int ndim);

int sep_nsubbox(double cf, double delta, double lbox);
double sep_box_length(double dens, int npart, int ndim);
int sep_count_type(seppart *ptr,  char spec, int npart);
void sep_save_xyz(seppart *ptr, const char *partnames, 
		  const char *file, char *mode, sepsys sys);

double sep_eval_mom(seppart *ptr, int npart);
double sep_eval_mom_type(seppart *ptr, char type, int dir, int npart);
void sep_set_density(seppart *ptr, char typef, char typet, 
                     double densf, double denst, int npart);

double sep_wall(seppart *ptr, double (*Fun)(double, char), sepsys sys);
void sep_force_x0(seppart *ptr, char type, 
		  double (*fun)(double, char), sepsys *sys);
void sep_profs_bin(seppart *ptr, double *svel, double *momc, 
		   double *dens,  double *temp, int lvec, const double x[6], 
		   int dir, int dirvel, char type, 
		   long unsigned int *ncall, int opt, int npart);
void sep_rand32_init(int *r250_index, int *r521_index, 
                     unsigned long *r250_buffer, 
                     unsigned long *r521_buffer);
double sep_rand32(void);
double sep_randn(void);

void sep_hs_update(sepatom *ptr, int ip, int jp, double tc, int flag,  
		   double lbox, size_t natoms, size_t ndim);
int sep_hscoll(int *ip, int *jp, double *tc,  seppart *ptr, int *list, 
	       sepsys sys);
int sep_hs_coll(int *ip, int *jp, double *tc,  seppart *ptr, sepsys sys);
void sep_berendsen(sepatom *ptr, double Pd, double beta, sepret *ret, sepsys *sys);

void sep_compress_box(sepatom *ptr, double rhoD, double xi, sepsys *sys);
void sep_compress_box_dir(sepatom *ptr, double rhoD, double xi, 
			  int dir, sepsys *sys);

double sep_dist_ij(double *r, seppart *ptr, int i, int j, sepsys sys);

void sep_reset_force_mol(sepsys *sys);
void sep_berendsen_mol(sepatom *ptr, sepmol *mol, double Pd, 
		       double beta, sepret *ret, sepsys *sys);

void sep_set_omp(sepsys *sys);

void sep_set_skin(sepsys *sys, double value);
void sep_set_ldiff(sepatom *ptr, char type, double ldiff, sepsys sys);
void sep_set_charge(seppart *ptr, char type, double z, sepsys sys);
void sep_set_mass(seppart *ptr, char type, double m, sepsys sys);

void sep_set_type(seppart *ptr,  char spec, int numb, int npart);
void sep_set_x0(seppart *ptr, int npart);
void sep_set_xn(seppart *ptr, int npart);

void sep_reset_momentum(seppart *ptr, sepsys sys);
void sep_set_ndof(size_t ndof, sepsys *sys);

void sep_eval_xtrue(seppart *ptr, sepsys sys);

#endif




